<?php

class Eshanghu
{
    const WECHAT_NATIVE_URL = 'https://1shanghu.com/api/wechat/native';

    public $appKey;
    public $appSecret;
    public $subMchId;
    public $notify;

    public function __construct($config)
    {
        $this->appKey = $config['app_key'];
        $this->appSecret = $config['app_secret'];
        $this->subMchId = $config['sub_mch_id'];
        $this->notify = $config['notify'];
    }

    public function create($outTradeNo, $subject, $totalFee, $extra = '')
    {
        $data = [
            'app_key' => $this->appKey,
            'out_trade_no' => $outTradeNo,
            'total_fee' => $totalFee,
            'subject' => $subject,
            'extra' => $extra,
            'notify_url' => $this->notify,
        ];
        $data['sign'] = self::getSign($data, $this->appSecret);

        return $this->request(self::WECHAT_NATIVE_URL, $data);
    }

    /**
     * 回调验证
     *
     * @param array $data
     *
     * @return array
     *
     * @throws SignErrorException
     */
    public function callback($data)
    {
        if (! self::verify($data, $data['sign'], $this->appSecret)) {
            return false;
        }

        return $data;
    }

    /**
     * 请求
     *
     * @param $url
     * @param array $data
     *
     * @return mixed
     *
     * @throws EshanghuException
     * @throws HttpRequestErrorException
     */
    public function request($url, $data)
    {
      $curl = curl_init();
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_HEADER, 0);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($curl, CURLOPT_POST, 1);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
      $res = curl_exec($curl);
      curl_close($curl);
      $res = json_decode($res, true);
      if (!isset($res['data'])) {
        return [];
      }
      if ($res['code'] != 200) {
        return [];
      }
      return $res['data'];
    }

        /**
     * 获取签名.
     *
     * @param array  $data
     * @param string $appSecret
     *
     * @return string
     */
    public static function getSign($data, $appSecret)
    {
        ksort($data);
        $rows = [];
        foreach ($data as $key => $value) {
            if (! $value || $key == 'sign') {
                continue;
            }
            $rows[] = "{$key}={$value}";
        }
        $s = implode('&', $rows);
        $s .= $appSecret;

        return strtoupper(md5($s));
    }

    /**
     * 验证签名.
     *
     * @param array $data
     * @param $sign
     * @param $appSecret
     *
     * @return bool
     */
    public static function verify($data, $sign, $appSecret)
    {
        return strtoupper($sign) === self::getSign($data, $appSecret);
    }

}